using System;
using System.IO;
using System.Web;
using System.Xml;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington	
	Started:	2007-04-04	
	Status:		release	
	Version:	2.0.0
	Build:		20070702
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/

/*	-----------------------------------------------------------------------	
	Development Notes:
	==================
	20070404:	This class is a utility class that is used for the (simple for now)
				analysis of the log files created using log4net on a project.
				Its immediate aim s provide some basic functionality to retrieve 
				log entries and log entry selections.
	20070702:	Recompile for .Net 2.0
	-----------------------------------------------------------------------	*/

namespace umlungu.engineX.loggerX {
	/// <summary>Description of the enumeration</summary>
	public enum x_identifier {
		/// <summary>identifier description</summary>
	    idOne = 1,
		/// <summary>identifier description</summary>
	    idTwo = 2,
		/// <summary>identifier description</summary>
	    idThree = 3,
		/// <summary>identifier description</summary>
		idFour = 4
	}
	/// <summary>
	/// Description of the x_logalyse class.
	/// <para>Additional information about the class</para>
	/// </summary>
	public class x_logalyse {
		#region Invisible properties
		private string logDelimiter = ",";
		private char[]  logDelimiters;
		private string paramDelimiter = ":";
		private char[]  paramDelimiters;
		#endregion

		#region Constants
		private const string NAME_ENTRY = "log";
		private const string NAME_ENTRIES = "logs";
		private const string NAME_COUNT = "count";
		private const string NAME_PATH = "path";
		private const string NAME_FILTER = "filter";
		private const string DEFAULT_FILE = "log.txt";
		private const string DEFAULT_PATH_LOCAL = "logs";
		#endregion

		#region Visible properties
		private x_status status;
		/// <summary>Definiton of the status</summary>
		/// <value>Description of the value of the status</value>
		public x_status Status {
			get { return status; }
			set { status = value; }
		}
		private string filename = DEFAULT_FILE;
		/// <summary>The filename of the log file</summary>
		/// <value>Filename string (if not fully qualified path, assumes in the current directory)</value>
		public string Filename {
			get { return filename; }
			set { setFilename(value); }
		}
		private string path = "";
		/// <summary>The path to the log file</summary>
		/// <value>String containing the path</value>
		public string Path {
			//get { return filename; }
			set {
				path = String.Concat(value, "\\", DEFAULT_PATH_LOCAL);
				filename = String.Concat(value, "\\", DEFAULT_PATH_LOCAL, "\\", DEFAULT_FILE); 
			}
		}
		#endregion

		#region Constructors/Destructors
		/// <overloads>Constructor</overloads>
		/// <summary>Default constructor</summary>
		public x_logalyse() {
			initialise();
		}
		/// <summary>Constructor description</summary>
		/// <param name="path">The fully qualified path name of the log file</param>
		public x_logalyse(string path) {
			filename = path;
			initialise();
		}
		#endregion

		#region Public methods
		/// <overloads>Gets all the entries in a log file</overloads>
		/// <summary>Gets the current log file</summary>
		public void Get() {
			int count = 0;
			try {
				status.AddOk();
				XmlElement logs = status.AddElem(NAME_ENTRIES);
				count = addEntries(logs, count);
				logs.SetAttribute(NAME_COUNT, count.ToString());
	        } catch (Exception e) {
				status.AddError(e);
			}
			
		}
		/// <overloads>Gets selected entries in a log file</overloads>
		/// <summary>Gets the current log file</summary>
		public void Get(string filter) {
			int count = 0;
			try {
				status.AddOk();
				XmlElement logs = status.AddElem(NAME_ENTRIES);
				count = addEntries(logs, count, filter);
				logs.SetAttribute(NAME_COUNT, count.ToString());
				logs.SetAttribute(NAME_FILTER, filter);
	        } catch (Exception e) {
				status.AddError(e);
			}
		}
		/// <summary>Gets a specified log file archive</summary>
		/// <param name="FileDate">The numeric suffix of the log file to be got</param>
		public void Get(string filter, int FileDate) {
			setFilename(FileDate); 
			Get(filter);
		}
		/// <summary>Gets a specified log file archive</summary>
		/// <param name="FileDate">The numeric suffix of the log file to be got</param>
		public void Get(int FileDate) {
			setFilename(FileDate); 
			Get();
		}
		
		/// <overloads>Gets all the entries in a set of log files</overloads>
		/// <summary>Gets all log files</summary>
		public void Gets() {
			Gets(null);
		}
		/// <summary>Gets all log files with filter</summary>
		public void Gets(string filter) {
			int count = 0;
			try {
				status.AddOk();
				XmlElement logs = status.AddElem(NAME_ENTRIES);
		        DirectoryInfo di = new DirectoryInfo(path);
		        FileInfo[] fi = di.GetFiles();
		        foreach (FileInfo thisfile in fi) {
					filename = thisfile.Name;
					status.AddElem(logs, NAME_ENTRY, thisfile.Name);
		            //count = (filter == null || filter == "")? addEntries(logs, count) : addEntries(logs, count, filter);
				}
				logs.SetAttribute(NAME_PATH, path);
				logs.SetAttribute(NAME_COUNT, count.ToString());
				if (filter != null && filter != "")
					logs.SetAttribute(NAME_FILTER, filter);
	        } catch (Exception e) {
				status.AddError(e);
			}
			
		}
		/// <summary>Gets log files within a month</summary>
		/// <param name="year">The year of the log file archives</param>
		/// <param name="month">The month of the log file archives</param>
		public void Gets(int year, int month) {
			Gets(null, year, month);
		}
		/// <summary>Gets log files within a month</summary>
		/// <param name="year">The year of the log file archives</param>
		/// <param name="month">The month of the log file archives</param>
		public void Gets(string filter, int year, int month) {
		}
		
		#endregion
		
		#region Protected methods
		/// <summary>Description of this method</summary>
		protected void _Example() {
		}
		#endregion
		
		#region Private methods
		/// <summary>Description of this method</summary>
		private void initialise() {
			status = new x_status();
			logDelimiters = logDelimiter.ToCharArray();
			paramDelimiters = paramDelimiter.ToCharArray();
		}
		private bool getLine(XmlElement parent, string line) {
			string[] toks = line.Split(logDelimiters);
			XmlElement entry = status.AddElem(parent, NAME_ENTRY, toks[3]);
			entry.SetAttribute("type", toks[1]);
			entry.SetAttribute("datetime", toks[0]);
			return true;
		}
		private bool getLine(XmlElement parent, string line, string select) {
			string[] toks = line.Split(logDelimiters);
			string[] parms = toks[3].Split(paramDelimiters);
			if (select == parms[0]) {
				XmlElement entry = status.AddElem(parent, NAME_ENTRY, parms[1]);
				entry.SetAttribute("type", toks[1]);
				entry.SetAttribute("datetime", toks[0]);
				return true;
			} else
				return false;
		}
		private void setFilename(string LogFilename) {
			filename = String.Concat(path, "\\", LogFilename);
		}
		private void setFilename(int FileDate) {
			filename = String.Concat(path, "\\", DEFAULT_FILE, FileDate.ToString()); 
		}
		private int addEntries(XmlElement entries, int counter) {
			using (StreamReader rdr = new StreamReader(filename)) {
				String line;
				while ((line = rdr.ReadLine()) != null) {
					if (getLine(entries, line))
						counter++;
				}
			}
			return counter;
		}
		private int addEntries(XmlElement entries, int counter, string filter) {
			using (StreamReader rdr = new StreamReader(filename)) {
				String line;
				while ((line = rdr.ReadLine()) != null) {
					if (getLine(entries, line, filter))
						counter++;
				}
			}
			return counter;
		}
		#endregion
	}
}
